import csv
import re

from common import file_mgmt
from f10 import f10_comparator


class ContentHandler:
    def __init__(self):

        self._res = dict()  # {code-:{latest:, special:, f1_time:, shareholder: ,f4_time:},...}
        self.r1 = [
            (
                re.compile(
                    "[\d]{2}([\d]{2}-[\d]{2})-[\d]{2}[^每]*每股资本(公)积[：:]([^营]+营)业收入\(万元\)[：:]([\d\s.｜-]+)(?:同比增([^%]+%))?"),
                "每股资本公积"),
            # (?: $$)? 有同比增则取，无则略
            (re.compile(
                "[\d]{2}([\d]{2}-[\d]{2})-[\d]{2}[^每]*每股(未)分利润[：:]([^净]+净)利润\(万元\)[：:]([\d\s.｜-]+)(?:同比增([^%]+%))?"),
             "每股未分利润"),
            (re.compile("【质押占比】[：:]([^\d]+[^%]+%)"), "质押占比"),
            (re.compile("发行前股份(限售)流通\(([\d-]{10})\)[：:]([^股]+)股"), "发行前股份限售流通"),
            (re.compile("★(股改限售)流通\(([\d-]{10})\)[:：]{1}([^|]+?)｜"), "股改限售流通"),
            (re.compile("(增发A)股法人配售上市\(([\d-]{10})\)[：:]([^股]+)股"), "增发A股法人配售上市"),
            (re.compile("股权(激励)限售流通\(([\d-]{10})\)[：:]([^股]+)股"), "股权激励限售流通"),
            (re.compile("无限售不减持(承诺)到期\(([\d-]{10})\)[：:]([^股]+)股"), "无限售不减持承诺到期"),
            (re.compile("更新日期[：:][\d]{4}-([\d]{2}-[\d]{2})◇"), "更新日期")

        ]
        self.r4 = [(re.compile("【1\.控股股东与实际控制人】[^实]{10,}实际控制人([^(]+)\([^\d]+([^%]+%)[^%]*【2\.股东持股变动】"), "实际-"),
                   (re.compile("【1\.控股股东与实际控制人】[^第]{10,}第一大股东[^｜]*｜([^｜]+)｜[^【]*【"), "第一-"),
                   (re.compile("【1\.控股股东与实际控制人】[^控]{10,}控股股东[^｜^与]*｜([^｜]+)｜[^【]*【"), "控股-"),
                   re.compile("更新日期[：:][\d]{4}-([\d]{2}-[\d]{2})◇")
                   ]

    def get_res(self):
        return self._res

    def _filter(self, s):
        d = {"[｜┬┴─┼├┤└┘┌┐\s]+": " ", "公 ": "公", "营 ": " 营", "未 ": "未", "净 ": " 净"}

        for i in d:
            s = re.sub(i, d[i], s)
        return s.strip()

    def _save(self, dic, res):  # {code-:{latest:, special:, f1_time:, shareholder: ,f4_time:},...}
        for code in dic:
            payload = dic[code]
            if code in res:
                for x in payload:
                    res[code][x] = payload[x]

            else:
                res[code] = payload
            return res

    def handle(self, row):  # main
        code, content, flag = row["code"], row["content"], row["flag"]

        if flag == "1":
            dic = self._flag1(code, content)
        else:
            dic = self._flag4(code, content)
        self._save(dic, self._res)  # save to the global result list
        return self._res

    def _flag1(self, code, content):
        if content == "EMPTY":
            return {code: {"latest": content,
                           "special": content,
                           "f1_time": ""}
                    }
        spec = self.extractor(code, content, 2, 8)
        if spec == "":
            spec = "无"
        return {code: {"latest": self.extractor(code, content, 0, 2).strip(),
                       "special": spec.strip(),
                       "f1_time": self.extractor(code, content, 8, 9).strip()}
                }

    def extractor(self, code, content, a, b):
        s = ""

        for i in self.r1[a:b]:
            if i[1] == "质押占比":
                t = re.findall(i[0], content)
                # 找出质押的所有“行”，每行中去掉换行br和空格，再提取subject和percentage
                if t:
                    for tup_of_line in t:
                        tup_of_line = re.sub('[\s｜]+', '', tup_of_line)
                        tt = re.search('控股股东(.+)累计质押占其持股比例([\d.]+%)', tup_of_line)
                        # if tt is None:
                        #     print(code,tup_of_line)
                        s += '质押 ' + ' '.join(self._filter(x) for x in tt.groups() if x) + '\r\n'

            else:
                t = re.search(i[0], content)
                if t:
                    s += " ".join(self._filter(x) for x in t.groups() if x) + "\r\n"

            if not t and i[1] in content:
                print("Keyword {} presents in {} but RE failed to find it.".format(code, i[1]))

        return s

    def _flag4(self, code, content):
        # empty resp
        if content == "EMPTY":
            return {code: {"shareholder": content, "f4_time": ""}}
        f4_time = re.search(self.r4[-1], content).group(1)
        shareholder_s = ""
        for reg in self.r4[:len(self.r4) - 1]:
            t = re.search(reg[0], content)
            if t:
                if len(shareholder_s) > 0:
                    shareholder_s += "\n"
                shareholder_s += reg[1] + " ".join(self._filter(x) for x in t.groups() if x)
        if len(shareholder_s) > 0:
            return {code: {"shareholder": shareholder_s.strip(), "f4_time": f4_time.strip()}}
        else:
            return {code: {"shareholder": "无", "f4_time": f4_time.strip()}}


# find interesting parts of a given raw csv
def run(path_to_process, g_path=''):
    file_name = path_to_process
    with open(file_name, newline='', encoding="utf-8-sig", errors="ignore") as csvfile:
        reader = csv.DictReader(csvfile)
        handler = ContentHandler()
        count = 0
        for row in reader:
            count += 1
            handler.handle(row)
        ana_res = handler.get_res()
        with open(file_name.replace('res', 'ana'), 'w', newline='', encoding="utf-8-sig", errors="ignore") as csvfile:
            fieldnames = ['code', 'latest', 'special', 'f1_time', 'shareholder', 'f4_time']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

            writer.writeheader()

            for i in ana_res:
                try:
                    ana_res[i]["code"] = i
                    writer.writerow(ana_res[i])
                except Exception as x:
                    print('Failure in writing f10 ana')
                    print(str(x))

            latest_ana = file_mgmt.push(dir=g_path + "ana", ext='csv')[1]
            # expectantly from yesterday
            latest_bin = file_mgmt.push(dir=g_path + "bin_bare", ext='bin')[1]
            print("--------------------- f10 ana produced  --------------------")
            if latest_bin and latest_ana:
                f10_comparator.run(latest_bin, latest_ana, g_path)
            else:
                raise Exception("Comparision requires 2 params. ")


if __name__ == '__main__':
    run("res_2020-04-27.csv", g_path="")
